﻿using System;

namespace Patterns.State {
    public static class AbstractExample {

        public static void Run() {
            // Setup context in a state
            Context c = new Context(new ConcreteStateA());

            // Issue requests, which toggles state
            c.Request();
            c.Request();
            c.Request();
            c.Request();
        }
    }

    // "State"
    abstract class AbstractState {
        public abstract void Handle(Context context);
    }

    // "ConcreteStateA"
    class ConcreteStateA : AbstractState {
        public override void Handle(Context context) {
            context.State = new ConcreteStateB();
        }
    }

    // "ConcreteStateB"
    class ConcreteStateB : AbstractState {
        public override void Handle(Context context) {
            context.State = new ConcreteStateA();
        }
    }

    // "Context"
    class Context {
        private AbstractState state;

        // Constructor
        public Context(AbstractState state) {
            this.State = state;
        }

        // Property
        public AbstractState State {
            get { return state; }
            set {
                state = value;
                Console.WriteLine("State: " +
                  state.GetType().Name);
            }
        }

        public void Request() {
            state.Handle(this);
        }
    }
}
